ti: k3: common: Enable GICv3 support
authorNishanth Menon <[email protected]>
Fri, 14 Oct 2016 01:13:49 +0000 (01:13 +0000)
committerAndrew F. Davis <[email protected]>
Tue, 19 Jun 2018 17:42:37 +0000 (12:42 -0500)
Do proper initialization of GIC V3. This will allow CP15 access to GIC
from "normal world" (aka HLOS) via mrc/mcr calls.

K3 SoC family uses GICv3 compliant GIC500 without compatibility for
legacy GICv2.

Signed-off-by: Nishanth Menon <[email protected]>
Signed-off-by: Benjamin Fair <[email protected]>
Signed-off-by: Andrew F. Davis <[email protected]>
plat/ti/k3/common/k3_bl31_setup.c
plat/ti/k3/common/k3_gicv3.c [new file with mode: 0644]
plat/ti/k3/common/plat_common.mk
plat/ti/k3/include/k3_gicv3.h [new file with mode: 0644]
plat/ti/k3/include/platform_def.h

index dea2802ebc6d2de91106f5512ddfc8e32c07adf1..ca7d214a16bacadf411cb4a3a4ff4cbe1abae97b 100644 (file)
 #include <k3_console.h>
 #include <plat_arm.h>
 #include <platform_def.h>
+#include <k3_gicv3.h>
 #include <string.h>
 
 /* Table of regions to map using the MMU */
 const mmap_region_t plat_arm_mmap[] = {
        MAP_REGION_FLAT(SHARED_RAM_BASE, SHARED_RAM_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
        MAP_REGION_FLAT(K3_USART_BASE_ADDRESS, K3_USART_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+       MAP_REGION_FLAT(K3_GICD_BASE, K3_GICD_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+       MAP_REGION_FLAT(K3_GICR_BASE, K3_GICR_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
        { /* sentinel */ }
 };
 
@@ -107,7 +110,8 @@ void bl31_plat_arch_setup(void)
 
 void bl31_platform_setup(void)
 {
-       /* TODO: Initialize the GIC CPU and distributor interfaces */
+       k3_gic_driver_init(K3_GICD_BASE, K3_GICR_BASE);
+       k3_gic_init();
 }
 
 void platform_mem_init(void)
diff --git a/plat/ti/k3/common/k3_gicv3.c b/plat/ti/k3/common/k3_gicv3.c
new file mode 100644 (file)
index 0000000..3253130
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <gicv3.h>
+#include <interrupt_props.h>
+#include <k3_gicv3.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <utils.h>
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+static const interrupt_prop_t k3_interrupt_props[] = {
+       PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
+       PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0)
+};
+
+static unsigned int k3_mpidr_to_core_pos(unsigned long mpidr)
+{
+       return (unsigned int)plat_core_pos_by_mpidr(mpidr);
+}
+
+gicv3_driver_data_t k3_gic_data = {
+       .rdistif_num = PLATFORM_CORE_COUNT,
+       .rdistif_base_addrs = rdistif_base_addrs,
+       .interrupt_props = k3_interrupt_props,
+       .interrupt_props_num = ARRAY_SIZE(k3_interrupt_props),
+       .mpidr_to_core_pos = k3_mpidr_to_core_pos,
+};
+
+void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base)
+{
+       /*
+        * The GICv3 driver is initialized in EL3 and does not need
+        * to be initialized again in SEL1. This is because the S-EL1
+        * can use GIC system registers to manage interrupts and does
+        * not need GIC interface base addresses to be configured.
+        */
+       k3_gic_data.gicd_base = gicd_base;
+       k3_gic_data.gicr_base = gicr_base;
+       gicv3_driver_init(&k3_gic_data);
+}
+
+void k3_gic_init(void)
+{
+       gicv3_distif_init();
+       gicv3_rdistif_init(plat_my_core_pos());
+       gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+void k3_gic_cpuif_enable(void)
+{
+       gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+void k3_gic_cpuif_disable(void)
+{
+       gicv3_cpuif_disable(plat_my_core_pos());
+}
+
+void k3_gic_pcpu_init(void)
+{
+       gicv3_rdistif_init(plat_my_core_pos());
+}
index 56a60a8dd6f6388e13710d2fde3143e79667d6c5..0c153f746a09275ef8139293f9a4fb97dd2881bd 100644 (file)
@@ -42,6 +42,13 @@ K3_CONSOLE_SOURCES   +=      \
                                drivers/ti/uart/aarch64/16550_console.S \
                                ${PLAT_PATH}/common/k3_console.c        \
 
+K3_GIC_SOURCES         +=      \
+                               drivers/arm/gic/common/gic_common.c     \
+                               drivers/arm/gic/v3/gicv3_main.c         \
+                               drivers/arm/gic/v3/gicv3_helpers.c      \
+                               plat/common/plat_gicv3.c                \
+                               ${PLAT_PATH}/common/k3_gicv3.c          \
+
 PLAT_BL_COMMON_SOURCES +=      \
                                plat/arm/common/arm_common.c            \
                                lib/cpus/aarch64/cortex_a53.S           \
@@ -52,3 +59,4 @@ BL31_SOURCES          +=      \
                                ${PLAT_PATH}/common/k3_bl31_setup.c     \
                                ${PLAT_PATH}/common/k3_helpers.S        \
                                ${PLAT_PATH}/common/k3_topology.c       \
+                               ${K3_GIC_SOURCES}                       \
diff --git a/plat/ti/k3/include/k3_gicv3.h b/plat/ti/k3/include/k3_gicv3.h
new file mode 100644 (file)
index 0000000..bbf5bf9
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __K3_GICV3_H__
+#define __K3_GICV3_H__
+
+void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base);
+void k3_gic_init(void);
+void k3_gic_cpuif_enable(void);
+void k3_gic_cpuif_disable(void);
+void k3_gic_pcpu_init(void);
+
+#endif /* __K3_GICV3_H__ */
index a82bb362dac34bfead6a34c9d2b19b5d30fae802..8856af2ca868b1db53c980c5b2d22b428c61f9c4 100644 (file)
 #define SYS_COUNTER_FREQ_IN_TICKS 200000000
 #endif
 
+/* Interrupt numbers */
+#define ARM_IRQ_SEC_PHY_TIMER          29
+
+#define ARM_IRQ_SEC_SGI_0              8
+#define ARM_IRQ_SEC_SGI_1              9
+#define ARM_IRQ_SEC_SGI_2              10
+#define ARM_IRQ_SEC_SGI_3              11
+#define ARM_IRQ_SEC_SGI_4              12
+#define ARM_IRQ_SEC_SGI_5              13
+#define ARM_IRQ_SEC_SGI_6              14
+#define ARM_IRQ_SEC_SGI_7              15
+
+/*
+ * Define properties of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
+       INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+                       GIC_INTR_CFG_LEVEL), \
+       INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
+                       GIC_INTR_CFG_EDGE), \
+       INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \
+                       GIC_INTR_CFG_EDGE), \
+       INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \
+                       GIC_INTR_CFG_EDGE), \
+       INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \
+                       GIC_INTR_CFG_EDGE), \
+       INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \
+                       GIC_INTR_CFG_EDGE), \
+       INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \
+                       GIC_INTR_CFG_EDGE)
+
+#define PLAT_ARM_G0_IRQ_PROPS(grp) \
+       INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
+                       GIC_INTR_CFG_EDGE), \
+       INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
+                       GIC_INTR_CFG_EDGE)
+
+#define K3_GICD_BASE  0x01800000
+#define K3_GICD_SIZE  0x10000
+#define K3_GICR_BASE  0x01880000
+#define K3_GICR_SIZE  0x100000
+
 #endif /* __PLATFORM_DEF_H__ */